import { Client } from "./mod.ts";
import { User, PublicKey, CreateKeyOption } from "./user.ts";
import { Repository, CreateRepoOption } from "./repo.ts";
import { Organization, Team, CreateOrgOption, CreateTeamOption } from "./org.ts";

/**
 * Options for creating a user
 */
export interface CreateUserOption {
  source_id?: number;
  login_name?: string;
  username: string;
  full_name?: string;
  email: string;
  password?: string;
  send_notify?: boolean;
}

/**
 * Options for editing a user
 */
export interface EditUserOption {
  source_id?: number;
  login_name?: string;
  full_name?: string;
  email: string;
  password?: string;
  website?: string;
  location?: string;
  active?: boolean;
  admin?: boolean;
  allow_git_hook?: boolean;
  allow_import_local?: boolean;
  max_repo_creation?: number;
}

/**
* Options for forking a repository
*/
export interface AdminForkRepoOption {
 repo_name: string;
 repo_owner: string;
 source_repo_name: string;
 description?: string;
 organization?: string;
}

/**
 * Admin API endpoints for managing Gogs instance
 */
export class AdminAPI {
  constructor(private client: Client) {}

  // User management

  /**
   * Create a new user
   */
  async createUser(options: CreateUserOption): Promise<User> {
    return await this.client.doRequest<User>(
      "POST", 
      "/admin/users", 
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Edit a user
   */
  async editUser(username: string, options: EditUserOption): Promise<void> {
    await this.client.doRequest<void>(
      "PATCH", 
      `/admin/users/${username}`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Delete a user
   */
  async deleteUser(username: string): Promise<void> {
    await this.client.doRequest<void>(
      "DELETE", 
      `/admin/users/${username}`
    );
  }

  /**
   * Create a public key for a user
   */
  async createUserPublicKey(username: string, options: CreateKeyOption): Promise<PublicKey> {
    return await this.client.doRequest<PublicKey>(
      "POST", 
      `/admin/users/${username}/keys`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  // Organization management

  /**
   * Create an organization for a user
   */
  async createOrg(username: string, options: CreateOrgOption): Promise<Organization> {
    return await this.client.doRequest<Organization>(
      "POST", 
      `/admin/users/${username}/orgs`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Create a team for an organization
   */
  async createTeam(orgname: string, options: CreateTeamOption): Promise<Team> {
    return await this.client.doRequest<Team>(
      "POST", 
      `/admin/orgs/${orgname}/teams`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Add a user to a team
   */
  async addTeamMembership(teamID: number, username: string): Promise<void> {
    await this.client.doRequest<void>(
      "PUT", 
      `/admin/teams/${teamID}/members/${username}`, 
      { "Content-Type": "application/json" }
    );
  }

  /**
   * Add a repository to a team
   */
  async addTeamRepository(teamID: number, reponame: string): Promise<void> {
    await this.client.doRequest<void>(
      "PUT", 
      `/admin/teams/${teamID}/repos/${reponame}`, 
      { "Content-Type": "application/json" }
    );
  }

  // Repository management

  /**
   * Create a repository for a user
   */
  async createRepo(username: string, options: CreateRepoOption): Promise<Repository> {
    return await this.client.doRequest<Repository>(
      "POST", 
      `/admin/users/${username}/repos`, 
      { "Content-Type": "application/json" },
      options
    );
  }

  /**
   * Fork a repository for a user 
   * @param username - The username who will own the fork
   * @param options - Fork options
   * @param repoOwner - Owner of the source repository
   * @param repoName - Name of the source repository
   */
  async forkRepo(username: string, options: AdminForkRepoOption): Promise<Repository> {

    
    return await this.client.doRequest<Repository>(
      "POST", 
      `/admin/users/${username}/repos/fork`, 
      { "Content-Type": "application/json" },
      options
    );
  }
} 